package com.sqlcheck.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 大模型配置类
 */
@ConfigurationProperties(prefix = "llm")
@Component
@Data
@Validated
@Slf4j
public class LLMConfiguration implements InitializingBean {

    private boolean enabled = true;

    @NotBlank
    private String defaultProvider = "openai";

    private Duration defaultTimeout = Duration.ofSeconds(30);

    private int maxRetries = 3;

    @Valid
    private Map<String, ProviderConfig> providers = new HashMap<>();

    @Valid
    private RateLimitConfig rateLimit = new RateLimitConfig();

    @Valid
    private CacheConfig cache = new CacheConfig();

    @Valid
    private MonitoringConfig monitoring = new MonitoringConfig();

    @Valid
    private SecurityConfig security = new SecurityConfig();

    @Valid
    private PromptsConfig prompts = new PromptsConfig();

    @Data
    @Validated
    public static class ProviderConfig {

        @NotBlank
        private String apiUrl;

        private String apiKey;

        @Valid
        private List<ModelConfig> models = new ArrayList<>();

        private String defaultModel;

        private Double temperature = 0.1;

        private Map<String, String> headers = new HashMap<>();

        private Map<String, Object> additionalParams = new HashMap<>();
    }

    @Data
    @Validated
    public static class ModelConfig {

        @NotBlank
        private String name;

        private String displayName;

        private String description;

        @Min(1)
        private Integer maxTokens = 4000;

        private Double costPer1kTokens;

        private boolean available = true;
    }

    @Data
    public static class RateLimitConfig {
        private boolean enabled = true;
        private int requestsPerMinute = 10;
        private int requestsPerDay = 100;
    }

    @Data
    public static class CacheConfig {
        private boolean enabled = true;
        private Duration promptCacheDuration = Duration.ofHours(1);
        private Duration resultCacheDuration = Duration.ofHours(24);
        private int maxCacheSize = 1000;
    }

    @Data
    public static class MonitoringConfig {
        private boolean enabled = true;
        private boolean metricsEnabled = true;
        private Duration slowRequestThreshold = Duration.ofSeconds(10);
    }

    @Data
    public static class SecurityConfig {
        private boolean apiKeyEncryption = true;
        private boolean requestLogging = false;
        private boolean responseFiltering = true;
        private List<String> ipWhitelist = new ArrayList<>();
    }

    @Data
    public static class PromptsConfig {
        private String templatePath = "classpath:prompts/";
        private String defaultTemplate = "default_optimization";
        private boolean cacheTemplates = true;
        private boolean validateTemplates = true;
    }

    /**
     * 获取提供商配置
     */
    public ProviderConfig getProvider(String providerName) {
        return providers.get(providerName);
    }

    /**
     * 获取默认提供商配置
     */
    public ProviderConfig getDefaultProviderConfig() {
        return providers.get(defaultProvider);
    }

    /**
     * 获取默认提供商名称
     */
    public String getDefaultProviderName() {
        return defaultProvider;
    }

    /**
     * 检查提供商是否可用
     */
    public boolean isProviderAvailable(String providerName) {
        ProviderConfig config = providers.get(providerName);
        return config != null && config.getApiKey() != null && !config.getApiKey().isEmpty();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("=== LLM配置加载完成 ===");
        log.info("LLM功能启用: {}", enabled);
        log.info("默认提供商: {}", defaultProvider);
        log.info("默认超时时间: {}", defaultTimeout);
        log.info("最大重试次数: {}", maxRetries);
        log.info("提供商数量: {}", providers.size());

        for (Map.Entry<String, ProviderConfig> entry : providers.entrySet()) {
            ProviderConfig config = entry.getValue();
            log.info("提供商 [{}]: API地址={}, 模型数量={}, 默认模型={}",
                    entry.getKey(), config.getApiUrl(),
                    config.getModels() != null ? config.getModels().size() : 0,
                    config.getDefaultModel());
        }
        log.info("========================");
    }
}